// ReaderSelfService.java - 读者自助服务类
package com.library.service;

import com.library.entity.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ReaderSelfService {
    private Map<String, BorrowRecord> borrowRecords;
    private Map<String, Reservation> reservations;
    private Map<String, Fine> fines;
    private LibraryDataService dataService;
    private AuthService authService;

    public ReaderSelfService(LibraryDataService dataService, AuthService authService) {
        this.borrowRecords = new ConcurrentHashMap<>();
        this.reservations = new ConcurrentHashMap<>();
        this.fines = new ConcurrentHashMap<>();
        this.dataService = dataService;
        this.authService = authService;
        initializeSampleData();
    }

    private void initializeSampleData() {
        // 初始化示例借阅记录
        borrowRecords.put("BR001", new BorrowRecord("BR001", "2023001", "9787115546081", 
            java.time.LocalDate.now().minusDays(10), java.time.LocalDate.now().plusDays(20)));
        borrowRecords.put("BR002", new BorrowRecord("BR002", "2023001", "9787111636664", 
            java.time.LocalDate.now().minusDays(5), java.time.LocalDate.now().plusDays(25)));

        // 初始化示例罚金记录
        fines.put("F001", new Fine("F001", "2023001", "BR003", 5.0, "图书超期"));
        fines.put("F002", new Fine("F002", "2023001", "BR004", 3.5, "图书超期"));
    }

    // 借阅相关方法
    public List<BorrowRecord> getReaderBorrowRecords(String readerId) {
        return borrowRecords.values().stream()
            .filter(record -> record.getReaderId().equals(readerId))
            .sorted((r1, r2) -> r2.getBorrowDate().compareTo(r1.getBorrowDate()))
            .collect(Collectors.toList());
    }

    public BorrowRecord getBorrowRecord(String recordId) {
        return borrowRecords.get(recordId);
    }

    public boolean renewBook(String recordId, String readerId) {
        BorrowRecord record = borrowRecords.get(recordId);
        if (record == null || !record.getReaderId().equals(readerId)) {
            return false;
        }

        Reader reader = dataService.findReaderById(readerId);
        if (reader == null) {
            return false;
        }

        BorrowRule rule = dataService.getBorrowRule(reader.getType());
        if (record.getRenewCount() >= rule.getMaxRenewTimes()) {
            return false; // 超过最大续借次数
        }

        if (record.isOverdue()) {
            return false; // 超期图书不能续借
        }

        // 续借操作
        record.setRenewCount(record.getRenewCount() + 1);
        record.setDueDate(record.getDueDate().plusDays(rule.getMaxBorrowDays()));
        return true;
    }

    // 预约相关方法
    public boolean reserveBook(String readerId, String bookIsbn) {
        Reader reader = dataService.findReaderById(readerId);
        if (reader == null) {
            return false;
        }

        Book book = dataService.findBookByIsbn(bookIsbn);
        if (book == null || book.getAvailableCopies() > 0) {
            return false; // 图书不存在或有可借复本，不需要预约
        }

        BorrowRule rule = dataService.getBorrowRule(reader.getType());
        if (!rule.canReserve()) {
            return false; // 该读者类型不能预约
        }

        // 检查是否已达到最大预约数
        long activeReservations = reservations.values().stream()
            .filter(r -> r.getReaderId().equals(readerId) && r.getStatus() == Reservation.ReservationStatus.ACTIVE)
            .count();
        if (activeReservations >= rule.getMaxReserveCount()) {
            return false;
        }

        // 创建预约记录
        String reservationId = "RES" + System.currentTimeMillis();
        Reservation reservation = new Reservation(reservationId, readerId, bookIsbn);
        reservations.put(reservationId, reservation);
        return true;
    }

    public List<Reservation> getReaderReservations(String readerId) {
        return reservations.values().stream()
            .filter(reservation -> reservation.getReaderId().equals(readerId))
            .sorted((r1, r2) -> r2.getReserveDate().compareTo(r1.getReserveDate()))
            .collect(Collectors.toList());
    }

    public boolean cancelReservation(String reservationId, String readerId) {
        Reservation reservation = reservations.get(reservationId);
        if (reservation != null && reservation.getReaderId().equals(readerId)) {
            reservation.setStatus(Reservation.ReservationStatus.CANCELLED);
            return true;
        }
        return false;
    }

    // 罚金相关方法
    public List<Fine> getReaderFines(String readerId) {
        return fines.values().stream()
            .filter(fine -> fine.getReaderId().equals(readerId))
            .sorted((f1, f2) -> f2.getCreateDate().compareTo(f1.getCreateDate()))
            .collect(Collectors.toList());
    }

    public double getTotalUnpaidFines(String readerId) {
        return fines.values().stream()
            .filter(fine -> fine.getReaderId().equals(readerId) && fine.getStatus() == Fine.FineStatus.UNPAID)
            .mapToDouble(Fine::getAmount)
            .sum();
    }

    public boolean payFine(String fineId, String readerId) {
        Fine fine = fines.get(fineId);
        if (fine != null && fine.getReaderId().equals(readerId) && fine.getStatus() == Fine.FineStatus.UNPAID) {
            fine.setStatus(Fine.FineStatus.PAID);
            fine.setPayDate(java.time.LocalDate.now());
            return true;
        }
        return false;
    }

    // 搜索相关方法
    public List<Book> searchAvailableBooks(String keyword) {
        return dataService.searchBooks(keyword).stream()
            .filter(book -> book.getAvailableCopies() > 0)
            .collect(Collectors.toList());
    }

    public List<Book> getPopularBooks() {
        return dataService.getAllBooks().stream()
            .sorted((b1, b2) -> Integer.compare(b2.getTotalCopies() - b2.getAvailableCopies(), 
                                              b1.getTotalCopies() - b1.getAvailableCopies()))
            .limit(10)
            .collect(Collectors.toList());
    }

    // 统计信息
    public Map<String, Object> getReaderStatistics(String readerId) {
        Map<String, Object> stats = new HashMap<>();
        
        List<BorrowRecord> records = getReaderBorrowRecords(readerId);
        long currentBorrows = records.stream()
            .filter(r -> r.getStatus() == BorrowRecord.BorrowStatus.BORROWED)
            .count();
        long overdueBorrows = records.stream()
            .filter(BorrowRecord::isOverdue)
            .count();
        
        stats.put("currentBorrows", currentBorrows);
        stats.put("overdueBorrows", overdueBorrows);
        stats.put("totalFines", getTotalUnpaidFines(readerId));
        stats.put("activeReservations", getReaderReservations(readerId).stream()
            .filter(r -> r.getStatus() == Reservation.ReservationStatus.ACTIVE)
            .count());
        
        return stats;
    }
}
